﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ScFramework.Core;
using UnityEngine.UI;
public partial class WorkshopLogic : LogicModuleBase<InputManager, SpriteManager>, ICombineSubUI
{
    public class DragManager
    {
        static Vector2 predictPosLocal = Vector2.zero;     //单格的预测坐标 离散的
        static Vector2 mousePositionLocal = Vector2.zero;  //不能强制转换

        public MeshEntityData entityDragging; 
        public int DeltaX { get; set; }
        public int DeltaY { get; set; }

        public int DeltaXOld { get; set; }
        public int DeltaYOld { get; set; }

        public static bool inDrag = false;                //是否有物体被拖拽
        public static int DragID { get; set; }

        public delegate void DragEndHandler(CombineUIEvent evt, int id);  
        public event DragEndHandler OnDragStop;

        public delegate void PredictChangeHandler(int id, int x, int y, int oldX, int oldY);
        public event PredictChangeHandler OnPredictChange;

        public delegate void DragStartHandler(int id);
        public event DragStartHandler OnDragStart;

        public delegate void WorkshopRefreshHandler();
        public event WorkshopRefreshHandler OnWorkshopRefresh;

        public DragManager()
        {
            DeltaX = DeltaY = DeltaXOld = DeltaYOld = -RAW;
        }

        public void DragVarInit(int id)
        {
            entityDragging = WorkshopLogic.currentEntity.Find(xx => xx.ID == id);

            var preX = entityDragging.Body.MeshPos.x;
            var preY = entityDragging.Body.MeshPos.y;

            List<Vector3Int> subList = FlipRotateManager.ListTransform(entityDragging);

            if (entityDragging.Body.PresentPos == 1)    //在拼装台中
            {
                foreach (var i in subList)
                {
                    Grid.GridList[preX + i.x][preY + i.y].isOccupied = false;
                    Grid.GridList[preX + i.x][preY + i.y].occupyID = default;
                }
                entityDragging.Body.PresentPos = 3;    //伏笔伏笔伏笔伏笔

                MeshEntityData tmp = currentEntityInWorkShop.Find(xx => xx.ID == id);
                currentEntityInWorkShop.Remove(tmp);

                DraggedEntityShow.DeleteEntitySprite(id, preX, preY, "InGrid");

                if (OnWorkshopRefresh != null)
                {
                    OnWorkshopRefresh();
                }
            }
            DeltaX = DeltaY = DeltaXOld = DeltaYOld = -RAW;

            inDrag = true;
            DragID = id;
        }

        public void DragStart(int id)
        {
            if (OnDragStart != null)
            {
                OnDragStart(id);    //就是DragVarInit
            }
            //跟随鼠标的图片设置为被拖拽图片

            MeshEntityData toShow = currentEntity.Find(xx => xx.ID == id);

            string path = "Sprite/EntitySprite/";
            path += toShow.Body.SpriteName;

            //path = path.Substring(0, path.Length - 2);
            //path += "Single";

            Sprite spriteimg = ResourceManager.Instance.Load<Sprite>(path);
            
            FlipRotateManager.SpriteTransform(toShow, withMouse, true);

            withMouse.transform.SetAsLastSibling();
            if (spriteimg == null)
            {
                Debug.Log("NULL!!!!");
            }
            withMouse.GetComponent<Image>().sprite = spriteimg;
            withMouse.SetActive(true);
        }
        /// <summary>
        /// 结束拖拽时发布拖拽结束事件 包含冲突判定
        /// </summary>
        public void DragStop(int id, int x, int y)
        {
            Debug.Log("STOPPING");
            inDrag = false;
            bool success = true;
            List<Vector3Int> subList = FlipRotateManager.ListTransform(entityDragging);

            if (IsDeltaXYOverFlow(x, y, entityDragging))
            {
                Debug.Log("FAIL TO SETTLE FOR 出界");
                //if (entityDragging.Body.PresentPos == 1)

                DraggedEntityShow.DeleteEntitySprite(id, x, y, "Predict");

                BackToBackpack(id);
                Grid.DebugDisPlayAll();
                success = false;
            }

            if (IsOccupied(x, y, entityDragging))
            {
                Debug.Log("FAIL TO SETTLE FOR 方格不可用");
                //if (entityDragging.Body.PresentPos == 1)
                /* #region shit
                 List<Vector3Int> dsubList = new List<Vector3Int>();
                 dsubList = FlipRotateManager.ListTransform(entityDragging);
                 foreach (var e in dsubList)
                 {
                     if (Grid.GridList[x + e.x][y + e.y].singleBlock.transform.Find("Predict") != null)
                     {
                         Grid.GridList[x + e.x][y + e.y].singleBlock.transform.Find("Predict").gameObject.SetActive(false);
                     }
                 }
                 #endregion*/
                DraggedEntityShow.DeleteEntitySprite(id, x, y, "Predict");
                BackToBackpack(id);
                Grid.DebugDisPlayAll();
                success = false;
            }
            if(success)
            {
                entityDragging.Body.MeshPos = new Vector3Int(x, y, 0);

                if (entityDragging.Body.PresentPos != 1)
                {
                    currentEntityInWorkShop.Add(entityDragging);
                    entityDragging.Body.PresentPos = 1; //1.在拼装台上
                }

                foreach (var e in subList)
                {
                    Grid.GridList[x + e.x][y + e.y].isOccupied = true;
                    Grid.GridList[x + e.x][y + e.y].occupyID = id;
                }

                if (OnDragStop != null)
                {
                    DraggedEntityShow.DeleteEntitySprite(id, x, y, "Predict");
                    OnDragStop(CombineUIEvent.BenchToBag, id);  
                }
                if (OnWorkshopRefresh != null)
                {
                    OnWorkshopRefresh();    //拼装台中的实体列表更新了
                }
                Debug.Log("THE " + WorkshopLogic.currentEntity[id-1].Name + " has been set  in " + x + " , " + y + " successfully");
            }
            Grid.DebugDisPlayAll();
            entityDragging = null;
            withMouse.SetActive(false);
        }

        public void PredictChange(int id, int x, int y, int oldX, int oldY)
        {
            if (OnPredictChange != null)
            {
                OnPredictChange(id, x, y, oldX, oldY);
            }
        }
        public void PredictBlockSearch(Vector2 mousePositionWorld)
        {
            if (DragManager.inDrag == false)
            {
                return;
            }
            #region 计算预测的格子坐标
            RectTransformUtility.ScreenPointToLocalPointInRectangle(workshop.GetComponent<RectTransform>(), mousePositionWorld, null, out mousePositionLocal);

            //Debug.Log("MOUSE : " + mousePositionLocal);

            //编号为(0,0)格子的本地坐标
            Vector2 baseBlockPosLocal = new Vector3(Grid.GridList[0][0].singleBlock.GetComponent<RectTransform>().localPosition.x,
                                                    Grid.GridList[0][0].singleBlock.GetComponent<RectTransform>().localPosition.y);
            predictPosLocal = baseBlockPosLocal;

            //预测的格子编号为(DeltaX,DeltaY)
            DeltaX = (int)Math.Round((mousePositionLocal.x - predictPosLocal.x) / BLOCKSIZE);
            DeltaY = (int)Math.Round((mousePositionLocal.y - predictPosLocal.y) / BLOCKSIZE);
            #endregion

            if (DeltaX != DeltaXOld || DeltaY != DeltaYOld)
            {
                PredictChange(DragID, DeltaX, DeltaY, DeltaXOld, DeltaYOld);
                DeltaXOld = DeltaX;
                DeltaYOld = DeltaY;
            }
        }
        public static void BackToBackpack(int id)
        {
            MeshEntityData homeComming = currentEntity.Find(xx => xx.ID == id);
            MeshEntityData homeCommingW = null;
            if (homeComming.Body.PresentPos == 1)
            {
                homeCommingW = currentEntityInWorkShop.Find(xx => xx.ID == id);
            }
            homeComming.Body.PresentPos = 2;    //2.beibao

            if (homeCommingW != null)
            {
                currentEntityInWorkShop.Remove(homeCommingW);
            }
            else
            {
                //Debug.LogWarning("往背包里退回了个寂寞");       ??????
            }
        }

        /*public static void ShowConflict(int id)
        {
            var toShowConflict = currentEntityInWorkShop.Find(x => x.ID == id);
            var goTmp = Grid.GridList[toShowConflict.Body.MeshPos.x][toShowConflict.Body.MeshPos.y].singleBlock.transform.Find("InGrid");
            SetSpriteColor(goTmp, Color.red);
            
        }*/
        private static void SetSpriteColor(GameObject go, Color color)
        {
            go.GetComponent<Image>().color = Color.red;
        }
        public static bool IsDeltaXYOverFlow(int x, int y)
        {
            if (x >= 0 && x < RAW && y >= 0 && y < COL)
            {
                return false;
            }
            else
                return true;
        }
        public static bool IsDeltaXYOverFlow(int x, int y, List<Vector3Int> subList)
        {
            foreach (var sub in subList)
            {
                //Debug.Log("CHECKING OVERFLOW" + sub.x + x + " , " + sub.y + y);
                if (sub.x + x < 0 || sub.x + x >= RAW || sub.y + y < 0 || sub.y + y >= COL)
                {
                    return true;
                }
            }
            return false;
        }
        public static bool IsDeltaXYOverFlow(int x, int y, MeshEntityData toShow)
        {
            List<Vector3Int> subList = new List<Vector3Int>();
            subList = FlipRotateManager.ListTransform(toShow);
            foreach (var sub in subList)
            {
                //Debug.Log("CHECKING OVERFLOW" + sub.x + x + " , " + sub.y + y);
                if (sub.x + x < 0 || sub.x + x >= RAW || sub.y + y < 0 || sub.y + y >= COL)
                {
                    return true;
                }
            }
            return false;
        }
        public static bool IsOccupied(int x, int y, MeshEntityData toShow)
        {
            List<Vector3Int> subList = new List<Vector3Int>();
            subList = FlipRotateManager.ListTransform(toShow);
            foreach (var sub in subList)
            {
                if (!IsDeltaXYOverFlow(x + sub.x, y + sub.y))
                {
                    if (Grid.GridList[x + sub.x][y + sub.y].isOccupied)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
}
